/********************************************************************************
    * 文件名称 ：E53_SF1.c
    * 作     者：小熊派开源社区
    * 版     本：V1.0
    * 编写日期 ：2019-5-27
    * 功     能：E53_SF1扩展板驱动
*********************************************************************************
    * 说    明 ：本例程配套小熊派开源社区开发板使用
    *
    * 淘     宝：https://shop336827451.taobao.com/
    * 论     坛：https://bbs.huaweicloud.com/forum/forum-734-1.html
    * 微信公众号：小熊派开源社区
*********************************************************************************/

#include "E53_SF1.h"
#include <board.h>
#include <rtdevice.h>
#include "math.h"

#define E53_SF1_ADC_DEV_NAME        "adc1"      /* ADC 设备名称 */
#define E53_SF1_ADC_DEV_CHANNEL     3           /* ADC 通道 */
#define REFER_VOLTAGE       341                 /* 参考电压 3.41V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS        (1 << 12)           /* 转换位数为12位 */

#define E53_SF1_BEEP_PWM_DEVICE  "pwm16"
#define E53_SF1_BEEP_PWM_CH      1

static rt_adc_device_t adc_dev;            /* ADC 设备句柄 */
static rt_uint32_t value;
static struct rt_device_pwm     *pwm_device = RT_NULL; //定义 pwm 设备指针
static float R0; // 元件在洁净空气中的阻值

/***************************************************************
* 函数名称: GetVoltage
* 说    明: 获取电压值函数
* 参    数: 无
*
* 返 回 值: 无
***************************************************************/
static float GetVoltage(void)
{
    int vol;
    value = rt_adc_read(adc_dev, E53_SF1_ADC_DEV_CHANNEL);
    vol = value * REFER_VOLTAGE / CONVERT_BITS;
    rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
    /* 转换为对应电压值 */
    return (float)value * REFER_VOLTAGE / CONVERT_BITS;
}

/***************************************************************
 * 函数名称: MQ2PPMCalibration
 * 说    明: 传感器校准函数
 * 参    数: 无
 * 返 回 值: 无
 ***************************************************************/
static void MQ2PPMCalibration(void)
{
    float voltage = GetVoltage();
    if (voltage != 0) {
        float RS = (MQ2_CONSTANT_1 - voltage) / voltage * RL;
        R0 = RS / pow(CAL_PPM / MQ2_CONSTANT_2, 1 / MQ2_CONSTANT_3);
    }
}

/***************************************************************
* 函数名称: E53_SF1_Init
* 说    明: 初始化E53_SF1扩展板
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void E53_SF1_Init(void)
{
    /* 查找设备 */
    adc_dev = (rt_adc_device_t)rt_device_find(E53_SF1_ADC_DEV_NAME);
    /* 使能设备 */
    rt_adc_enable(adc_dev, E53_SF1_ADC_DEV_CHANNEL);

    pwm_device = (struct rt_device_pwm *)rt_device_find(E53_SF1_BEEP_PWM_DEVICE);
    if (pwm_device == RT_NULL)
    {
        rt_kprintf("pwm device %s not found!\n", E53_SF1_BEEP_PWM_DEVICE);
    }
    rt_pwm_set(pwm_device, E53_SF1_BEEP_PWM_CH, 2000000, 1000000);

    rt_pin_mode(E53_GPIO2, PIN_MODE_OUTPUT);//输出模式
    
    MQ2PPMCalibration();
}

/***************************************************************
 * 函数名称: E53_SF1_Read_Data
 * 说    明: 获取PPM函数
 * 参    数: ppm 烟雾浓度
 * 返 回 值: 0 成功; -1 失败
 ***************************************************************/
int E53_SF1_Read_Data(float *ppm)
{
    float voltage, RS;

    voltage = GetVoltage();
    RS = (MQ2_CONSTANT_1 - voltage) / voltage * RL;     // 计算RS
    *ppm = MQ2_CONSTANT_2 * pow(RS / R0, MQ2_CONSTANT_3); // 计算ppm
    return 0;
}

/***************************************************************
* 函数名称: E53_SF1_LED_Set
* 说    明: E53_SF1开发板上的LED灯的亮灭控制
* 参    数: status,LED灯的状态
*                                    OFF,关灯
*                                    ON,开灯
* 返 回 值: 无
***************************************************************/
void E53_SF1_LED_Set(E53_SF1_Status status)
{
    if (status == ON) {
        rt_pin_write(E53_GPIO2, PIN_HIGH);
    }

    if (status == OFF) {
        rt_pin_write(E53_GPIO2, PIN_LOW);
    }    
}

/***************************************************************
* 函数名称: E53_SF1_Beep_Set
* 说    明: E53_SF1蜂鸣器报警与否
* 参    数: status,ENUM枚举的数据
*                                    OFF,蜂鸣器
*                                    ON,开蜂鸣器
* 返 回 值: 无
***************************************************************/
void E53_SF1_Beep_Set(E53_SF1_Status status)
{
  if (status == ON)
    rt_pwm_enable(pwm_device, E53_SF1_BEEP_PWM_CH);
  if (status == OFF)
    rt_pwm_disable(pwm_device, E53_SF1_BEEP_PWM_CH); 
}


